#pragma once

#include "ZNetworkReceiver.h"
#include "ZPoolObject.h"
#include <string>

namespace	Z	{

//------------------------------------------------------------------------------------------------------------------------
class	_ZNetworkApi	Socket
	:	public NetworkReceiver,
		public PoolObject
{
public:
	Socket(SOCKET so);
	virtual	~Socket();
	SOCKET	getHandle()	const	{	return mHandle;	}
	virtual	bool	shutdown()	{	return ::shutdown(mHandle, SD_BOTH) != SOCKET_ERROR;	}
	bool	create(int af, int type, int protocol, DWORD flags);
	void	close();
	bool	receive(LPWSABUF wsaBufs, DWORD wsaBufCount, LPWSAOVERLAPPED pOverlapped = nullptr);
	bool	send(LPWSABUF wsaBufs, DWORD wsaBufCount, LPWSAOVERLAPPED pOverlapped = nullptr);
	bool	connect(const std::string& address, u_short port);
	bool	setSendBufferSize(int kSize = 0);
	bool	setKeepAlive(ms_t time, ms_t interval);
	bool	setLinger(ms_t time);
	static	bool	loadLib();
	static	void	unloadLib();
	static	bool	getSockAddr(SOCKADDR_IN& sin, const std::string& address, u_short port);
private:
	bool	setReuse();
	bool	connect(SOCKADDR_IN& sin);

protected:
	SOCKET	mHandle;
};

}